import React, {Component} from 'react';

import {View, Text, ActivityIndicator, StyleSheet,FlatList, TouchableOpacity} from 'react-native';

import RefreshState from './RefreshState';

import PropTypes from 'prop-types';


export default class RefreshListView extends Component{

    static propTypes = {

        onHeaderRefresh: PropTypes.func, // 下拉刷新的方法，供外部调用

        onFooterRefresh: PropTypes.func, // 上拉加载的方法，供外部调用

    };

    constructor(props) {

        super(props);

        this.state = {

            isHeaderRefreshing: false, // 头部是否正在刷新

            isFooterRefreshing: false, // 尾部是否正在刷新

            footerState: RefreshState.Idle, // 尾部当前的状态，默认为Idle，不显示控件

        }

    }

    render() {

        return (

            <FlatList

                {...this.props}

                onRefresh={()=>{ this.beginHeaderRefresh() }}

                refreshing={this.state.isHeaderRefreshing}

                onEndReached={() => { this.beginFooterRefresh() }}

                onEndReachedThreshold={0.1} // 这里取值0.1（0~1之间不包括0和1），可以根据实际情况调整，取值尽量小

                ListFooterComponent={this._renderFooter}

            />

        )

    }



    _renderFooter = () => {

        return (

            <RefreshFooter

                state={this.state.footerState}

                onRetryLoading={()=>{

                    this.beginFooterRefresh()

                }}

            />

        )

    };

    /// 开始下拉刷新

    beginHeaderRefresh() {

        if (this.shouldStartHeaderRefreshing()) {

            this.startHeaderRefreshing();

        }

    }



/// 开始上拉加载更多

    beginFooterRefresh() {

        if (this.shouldStartFooterRefreshing()) {

            this.startFooterRefreshing();

        }

    }



    /***

     * 当前是否可以进行下拉刷新

     * @returns {boolean}

     *

     * 如果列表尾部正在执行上拉加载，就返回false

     * 如果列表头部已经在刷新中了，就返回false

     */

    shouldStartHeaderRefreshing() {

        if (this.state.footerState === RefreshState.refreshing ||

            this.state.isHeaderRefreshing ||

            this.state.isFooterRefreshing) {

            return false;

        }

        return true;

    }



    /***

     * 当前是否可以进行上拉加载更多

     * @returns {boolean}

     *

     * 如果底部已经在刷新，返回false

     * 如果底部状态是没有更多数据了，返回false

     * 如果头部在刷新，则返回false

     * 如果列表数据为空，则返回false（初始状态下列表是空的，这时候肯定不需要上拉加载更多，而应该执行下拉刷新）

     */

    shouldStartFooterRefreshing() {

        if (this.state.footerState === RefreshState.refreshing ||

            this.state.footerState === RefreshState.NoMoreData ||

            this.props.data.length === 0 ||

            this.state.isHeaderRefreshing ||

            this.state.isFooterRefreshing) {

            return false;

        }

        return true;

    }



}

class RefreshFooter extends Component {



    static propTypes = {

        onLoadMore: PropTypes.func,   // 加载更多数据的方法

        onRetryLoading: PropTypes.func, // 重新加载的方法

    };



    static defaultProps = {

        footerRefreshingText: "努力加载中",

        footerLoadMoreText: "上拉加载更多",

        footerFailureText: "点击重新加载",

        footerNoMoreDataText: "已全部加载完毕"

    };



    render() {

        let {state} = this.props;

        let footer = null;

        switch (state) {

            case RefreshState.Idle:

                // Idle情况下为null，不显示尾部组件

                break;

            case RefreshState.Refreshing:

                // 显示一个loading视图

                footer =

                    <View style={styles.loadingView}>

                        <ActivityIndicator size="small"/>

                        <Text style={styles.refreshingText}>{this.props.footerRefreshingText}</Text>

                    </View>;

                break;

            case RefreshState.CanLoadMore:

                // 显示上拉加载更多的文字

                footer =

                    <View style={styles.loadingView}>

                        <Text style={styles.footerText}>{this.props.footerLoadMoreText}</Text>

                    </View>;

                break;

            case RefreshState.NoMoreData:

                // 显示没有更多数据的文字，内容可以自己修改

                footer =

                    <View style={styles.loadingView}>

                        <Text style={styles.footerText}>{this.props.footerNoMoreDataText}</Text>

                    </View>;

                break;

            case RefreshState.Failure:

                // 加载失败的情况使用TouchableOpacity做一个可点击的组件，外部调用onRetryLoading重新加载数据

                footer =

                    <TouchableOpacity style={styles.loadingView} onPress={()=>{

                        this.props.onRetryLoading && this.props.onRetryLoading();

                    }}>

                        <Text style={styles.footerText}>{this.props.footerFailureText}</Text>

                    </TouchableOpacity>;

                break;

        }

        return footer;

    }

    /// 下拉刷新，设置完刷新状态后再调用刷新方法，使页面上可以显示出加载中的UI，注意这里setState写法

    startHeaderRefreshing() {

        this.setState(

            {

                isHeaderRefreshing: true

            },

            () => {

                this.props.onHeaderRefresh && this.props.onHeaderRefresh();

            }

        );

    }



/// 上拉加载更多，将底部刷新状态改为正在刷新，然后调用刷新方法，页面上可以显示出加载中的UI，注意这里setState写法

    startFooterRefreshing() {

        this.setState(

            {

                footerState: RefreshState.Refreshing,

                isFooterRefreshing: true

            },

            () => {

                this.props.onFooterRefresh && this.props.onFooterRefresh();

            }

        );

    }

    endRefreshing(footerState) {

        let footerRefreshState = footerState;

        if (this.props.data.length === 0) {

            footerRefreshState = RefreshState.Idle;

        }

        this.setState({

            footerState: footerRefreshState,

            isHeaderRefreshing: false,

            isFooterRefreshing: false

        })

    }

}



const styles = StyleSheet.create({

    loadingView: {

        flexDirection: 'row',

        justifyContent: 'center',

        alignItems: 'center',

        padding: 15,

    },

    refreshingText: {

        fontSize: 12,

        color: "#666666",

        paddingLeft: 10,

    },

    footerText: {

        fontSize: 12,

        color: "#666666"

    }

});
